<?php
/**
 * 兼容第三方插件补丁文件
 * @appapi 兼容重整
 */
defined('BY_JYA') or exit('error');
class WeUtility {
	private static function defineConst($obj){
		if ($obj instanceof WeBase) {
			if (!defined('MODULE_ROOT')) {
				define('MODULE_ROOT', dirname($obj->__define));
			}
			if (!defined('MODULE_URL')) {
				define('MODULE_URL', SITEROOT.'addons/'.$obj->modulename.'/');
			}
		}
	}
	public static function createModule($name) {
		global $_AR;
		static $file;
		$classname = ucfirst($name) . 'Module';
		if(!class_exists($classname)) {
			$file = ROOT_D . "/addons/{$name}/module.php";
			if(!is_file($file)) {
				$file = ROOT_D . "/framework/builtin/{$name}/module.php";
			}
			if(!is_file($file)) {
				trigger_error('Module Definition File Not Found', E_USER_WARNING);
				return null;
			}
			require $file;
		}
		if(!class_exists($classname)) {
			trigger_error('Module Definition Class Not Found', E_USER_WARNING);
			return null;
		}
		$o = new $classname();
		$o->uniacid = $o->weid = $_SESSION['uniacid'];
		$o->modulename = $name;
		$o->__define = $file;
		self::defineConst($o);
		if($o instanceof WeModule) {
			return $o;
		} else {
			trigger_error('类错误：', E_USER_WARNING);
			return null;
		}
	}
	public static function createModuleProcessor($name) {
		global $_AR;
		static $file;
		$classname = "{$name}ModuleProcessor";
		if(!class_exists($classname)) {
			$file = ROOT_D . "/addons/{$name}/processor.php";
			if(!is_file($file)) {
				$file = ROOT_D . "/framework/builtin/{$name}/processor.php";
			}
			if(!is_file($file)) {
				trigger_error('createModuleProcessor1：'.$file, E_USER_WARNING);
				return null;
			}
			require $file;
		}
		if(!class_exists($classname)) {
			trigger_error('createModuleProcessor2：', E_USER_WARNING);
			return null;
		}
		$o = new $classname();
		$o->uniacid = $o->weid = $_SESSION['uniacid'];
		$o->modulename = $name;
		$o->__define = $file;
		self::defineConst($o);
		if($o instanceof WeModuleProcessor) {
			return $o;
		} else {
			trigger_error('createModuleProcessor3', E_USER_WARNING);
			return null;
		}
	}
	public static function createModuleReceiver($name) {
		global $_AR;
		static $file;
		$classname = "{$name}ModuleReceiver";
		if(!class_exists($classname)) {
			$file = ROOT_D . "/addons/{$name}/receiver.php";
			if(!is_file($file)) {
				$file = ROOT_D . "/framework/builtin/{$name}/receiver.php";
			}
			if(!is_file($file)) {
				trigger_error('createModuleReceiver1 '.$file, E_USER_WARNING);
				return null;
			}
			require $file;
		}
		if(!class_exists($classname)) {
			trigger_error('createModuleReceiver2', E_USER_WARNING);
			return null;
		}
		$o = new $classname();
		$o->uniacid = $o->weid = $_SESSION['uniacid'];
		$o->modulename = $name;
		$o->__define = $file;
		self::defineConst($o);
		if($o instanceof WeModuleReceiver) {
			return $o;
		} else {
			trigger_error('createModuleReceiver3', E_USER_WARNING);
			return null;
		}
	}
	public static function createModuleSite($name) {
		global $_AR;
		static $file;
		$classname = "{$name}ModuleSite";
		if(!class_exists($classname)) {
			$file = ROOT_D . "/addons/{$name}/site.php";
			if(!is_file($file)) {
				$file = ROOT_D . "/framework/builtin/{$name}/site.php";
			}
			if(!is_file($file)) {
				trigger_error('createModuleSite1'.$file, E_USER_WARNING);
				return null;
			}
			require $file;
		}
		if(!class_exists($classname)) {
			trigger_error('createModuleSite2', E_USER_WARNING);
			return null;
		}
		$o = new $classname();
		$o->uniacid = $o->weid = $_SESSION['uniacid'];
		$o->modulename = $name;
		$o->__define = $file;
		self::defineConst($o);
		$o->inMobile = defined('IN_MOBILE');
		if($o instanceof WeModuleSite) {
			return $o;
		} else {
			trigger_error('createModuleSite3', E_USER_WARNING);
			return null;
		}
	}
	public static function createModuleCron($name) {
		global $_AR;
		static $file;
		$classname = "{$name}ModuleCron";
		if(!class_exists($classname)) {
			$file = ROOT_D . "/addons/{$name}/cron.php";
			if(!is_file($file)) {
				$file = ROOT_D . "/framework/builtin/{$name}/cron.php";
			}
			if(!is_file($file)) {
				trigger_error('createModuleCron1 '.$file, E_USER_WARNING);
				return error(-1006, 'createModuleCron2');
			}
			require $file;
		}
		if(!class_exists($classname)) {
			trigger_error('createModuleCron3', E_USER_WARNING);
			return error(-1007, 'createModuleCron4');
		}
		$o = new $classname();
		$o->uniacid = $o->weid = $_SESSION['uniacid'];
		$o->modulename = $name;
		$o->__define = $file;
		self::defineConst($o);
		if($o instanceof WeModuleCron) {
			return $o;
		} else {
			trigger_error('createModuleCron5', E_USER_WARNING);
			return error(-1008, 'createModuleCron6');
		}
	}
	public static function logging($op = 'info', $msg = '') {
		$file = ROOT_D . '/data/logs/' . date('Ymd') . '.log';
		mkdirs(dirname($file));
		$msgnotice = date('Y-m-d H:i:s') . " {$op} :n------------n";
		if(is_string($msg) && !in_array($msg, array('post', 'get'))) {
			$msgnotice .= "String:n{$msg}n";
		}
		if(is_array($msg)) {
			$msgnotice .= "Array:n";
			foreach($msg as $key => $value) {
				$msgnotice .= sprintf("%s : %s ;
		n", $key, $value);
			}
		}
		if($msg === 'get') {
			$msgnotice .= "GET:n";
			foreach($_GET as $key => $value) {
				$msgnotice .= sprintf("%s : %s ; n", $key, $value);
			}
		}
		if($msg === 'post') {
			$msgnotice .= "POST:n";
			foreach($_POST as $key => $value) {
				$msgnotice .= sprintf("%s : %s ; n", $key, $value);
			}
		}
		$msgnotice .= "n";
		$fp = fopen($file, 'a+');
		fwrite($fp, $msgnotice);
		fclose($fp);
	}
}
abstract class WeBase {
	public $modulename;
	public $module;
	public $weid;
	public $uniacid;
	public $__define;
	public function getSettings() {
		$setting=pdo_getcolumn('core_account_plugin_setting',array('uniacid'=>$_SESSION['uniacid'],'plugin'=>$this->modulename),'data');
		if($setting){
			$setting=json_decode($setting,true);
		}else{
			$setting=array();
		}
		return $setting;
	}
	public function saveSettings($settings) {
		$check=pdo_getcolumn('core_account_plugin_setting',array('uniacid'=>$_SESSION['uniacid'],'plugin'=>$this->modulename),'id');
		$data=array('data'=>ijson_encode($settings));
		if($check){
			pdo_update('core_account_plugin_setting',$data,array('uniacid'=>$_SESSION['uniacid'],'plugin'=>$this->modulename));
		}else{
			$data['uniacid']=$_SESSION['uniacid'];
			$data['plugin']=$this->modulename;
			pdo_insert('core_account_plugin_setting',$data);
		}
		return true;
	}
	protected function createMobileUrl($do, $query = array()) {
		$query['action'] = 'module';
		$query['do'] = $do;
		$query['m'] = strtolower($this->modulename);
		$url = './index.php?i='.$_SESSION['uniacid'].'&';
		$queryString = http_build_query($query, '', '&');
		$url .= $queryString;
		return $url;
	}
	protected function createWebUrl($do, $query = array()) {
		$query['action'] = 'module';
		$query['do'] = $do;
		$query['m'] = strtolower($this->modulename);
		$url = './index.php?';
		$queryString = http_build_query($query, '', '&');
		$url .= $queryString;
		return $url;
	}
	protected function template($file) {
		global $_AR;
		$name = strtolower($this->modulename);
		$defineDir = dirname($this->__define);
		if(defined('IN_SYS')) {
			$compile = ROOT_D . "/data/tpl/web/{$name}/{$file}.tpl.php";
			$source =$defineDir . "/template/{$file}.html";	
			if(!is_file($source)) {
				$source =$defineDir . "/{$file}.html";
				if(!is_file($source)){
					$source = ROOT_D . "/api/open_jyapi/template/{$file}.html";
				}
			}
		} else {
			$compile = ROOT_D . "/data/tpl/app/{$name}/{$file}.tpl.php";
			if(!is_file($source)) {
				$source = $defineDir . "/template/mobile/{$file}.html";
			}
		}
		if(!is_file($source)) {
			exit("Error: template source1 '{$source}' is not exist!");
		}
		$paths = pathinfo($compile);
		$compile = str_replace($paths['filename'], $_SESSION['uniacid'] . '_' . $paths['filename'], $compile);
		if (DEVELOP || !is_file($compile) || filemtime($source) > filemtime($compile)) {
			template_compile($source, $compile, true);
		}
		return $compile;
	}
}
abstract class WeModule extends WeBase {
	public function fieldsFormDisplay($rid = 0) {
		return '';
	}
	public function fieldsFormValidate($rid = 0) {
		return '';
	}
	public function fieldsFormSubmit($rid) {
	}
	public function ruleDeleted($rid) {
		return true;
	}
	public function settingsDisplay($settings) {
	}
}
abstract class WeModuleProcessor extends WeBase {
	public $priority;
	public $msgnotice;
	public $inContext;
	public $rule;
	public function __construct(){
		global $_AR;
		$_AR['member'] = array();
		if(!empty($_AR['openid'])){
			load()->model('mc');
			$_AR['member'] = mc_fetch($_AR['openid']);
		}
	}
	protected function beginContext($expire = 1800) {
		if($this->inContext) {
			return true;
		}
		start_context($this->modulename,$this->rule);
		$this->inContext = true;
		return true;
	}
	protected function refreshContext($expire = 1800) {
		if(!$this->inContext) {
			return false;
		}
		refresh_context();
		return true;
	}
	protected function endContext() {
		end_context();
	}
	abstract function respond();
	protected function respText($msgnotice) {
		if (empty($msgnotice)) {
			return error(-1, '内容为空');
		}
		if(stripos($msgnotice,'./') !== false) {
			preg_match_all('/<a .*?href="(.*?)".*?>/is',$msgnotice,$urls);
			if (!empty($urls[1])) {
				foreach ($urls[1] as $url) {
					$msgnotice = str_replace($url, $this->buildSiteUrl($url), $msgnotice);
				}
			}
		}
		$msgnotice = str_replace("rn", "n", $msgnotice);
		$notice = array();
		$notice['FromUserName'] = $this->message['to'];
		$notice['ToUserName'] = $this->message['from'];
		$notice['MsgType'] = 'text';
		$notice['Content'] = htmlspecialchars_decode($msgnotice);
		preg_match_all('/[U+(\w{4,})]/i', $notice['Content'], $matchArray);
		if(!empty($matchArray[1])) {
			foreach ($matchArray[1] as $emoj) {
				$notice['Content'] = str_ireplace("[U+{$emoj}]", utf8_bytes(hexdec($emoj)), $notice['Content']);
			}
		}
		return $notice;
	}
	protected function respImage($mid) {
		if (empty($mid)) {
			return error(-1, '内容为空');
		}
		$notice = array();
		$notice['FromUserName'] = $this->message['to'];
		$notice['ToUserName'] = $this->message['from'];
		$notice['MsgType'] = 'image';
		$notice['Image']['MediaId'] = $mid;
		return $notice;
	}
	protected function respVoice($mid) {
		if (empty($mid)) {
			return error(-1, '内容为空');
		}
		$notice = array();
		$notice['FromUserName'] = $this->message['to'];
		$notice['ToUserName'] = $this->message['from'];
		$notice['MsgType'] = 'voice';
		$notice['Voice']['MediaId'] = $mid;
		return $notice;
	}
	protected function respVideo(array $video) {
		if (empty($video)) {
			return error(-1, '内容为空');
		}
		$notice = array();
		$notice['FromUserName'] = $this->message['to'];
		$notice['ToUserName'] = $this->message['from'];
		$notice['MsgType'] = 'video';
		$notice['Video']['MediaId'] = $video['MediaId'];
		$notice['Video']['Title'] = $video['Title'];
		$notice['Video']['Description'] = $video['Description'];
		return $notice;
	}
	protected function respMusic(array $music) {
		if (empty($music)) {
			return error(-1, '内容为空');
		}
		global $_AR;
		$music = array_change_key_case($music);
		$notice = array();
		$notice['FromUserName'] = $this->message['to'];
		$notice['ToUserName'] = $this->message['from'];
		$notice['MsgType'] = 'music';
		$notice['Music'] = array(
			'Title' => $music['title'],
			'Description' => $music['description'],
			'MusicUrl' => tomedia($music['musicurl'])
		);
		if (empty($music['hqmusicurl'])) {
			$notice['Music']['HQMusicUrl'] = $notice['Music']['MusicUrl'];
		} else {
			$notice['Music']['HQMusicUrl'] = tomedia($music['hqmusicurl']);
		}
		if($music['thumb']) {
			$notice['Music']['ThumbMediaId'] = $music['thumb'];
		}
		return $notice;
	}
	protected function respNews(array $news) {
		global $_W;
		if (empty($news) || count($news) > 10) {
			return error('Invaild value');
		}
		$news = array_change_key_case($news);
		if (!empty($news['title'])) {
			$news = array($news);
		}
		$notice = array();
		$notice['FromUserName'] = $this->message['to'];
		$notice['ToUserName'] = $this->message['from'];
		$notice['MsgType'] = 'news';
		$notice['ArticleCount'] = count($news);
		$notice['Articles'] = array();
		foreach ($news as $row) {
			$notice['Articles'][] = array(
				'Title' => $row['title'],
				'Description' => ($notice['ArticleCount'] > 1) ? '' : $row['description'],
				'PicUrl' => tomedia($row['picurl']),
				'Url' =>  get_account_url(). 'custom/' .$row['url'],
				'TagName' => 'item'
			);
		}
		return $notice;
	}
	protected function respCustom(array $msgnotice = array()) {
		$notice = array();
		$notice['FromUserName'] = $this->message['to'];
		$notice['ToUserName'] = $this->message['from'];
		$notice['MsgType'] = 'transfer_customer_service';
		if (!empty($msgnotice['TransInfo']['KfAccount'])) {
			$notice['TransInfo']['KfAccount'] = $msgnotice['TransInfo']['KfAccount'];
		}
		return $notice;
	}
	protected function buildSiteUrl($url) {
		global $_AR;
		$mapping = array(
			'[from]' => $this->message['from'],
			'[to]' => $this->message['to'],
			'[rule]' => $this->rule,
			'[uniacid]' => $_SESSION['uniacid'],
		);
		$url = str_replace(array_keys($mapping), array_values($mapping), $url);
		if(strexists($url, 'http://') || strexists($url, 'https://')) {
			return $url;
		}
		if (strexists($url, './index.php?i=') && !strexists($url, '&j=') && !empty($_AR['acid'])) {
			$url = str_replace("?i={$_SESSION['uniacid']}&", "?i={$_SESSION['uniacid']}&j={$_AR['acid']}&", $url);
		}
		if ($_AR['account']['level'] == ACCOUNT_SERVICE_VERIFY) {
			return SITEROOT.'custom/' . $url;
		}
		return SITEROOT.'custom/' . $url;
	}
	protected function extend_W(){
		global $_AR;
		if(!empty($_AR['openid'])){
			load()->model('mc');
			$_AR['member'] = mc_fetch($_AR['openid']);
		}
		if(empty($_AR['member'])){
			$_AR['member'] = array();
		}
		if(!empty($_AR['acid'])){
			if (empty($_AR['uniaccount'])) {
				$_AR['uniaccount'] = $_SESSION['account'];
			}
			if (empty($_AR['account'])) {
				$_AR['account'] = $_SESSION['account'];
			}
		}
	}
}
abstract class WeModuleReceiver extends WeBase {
	public $params;
	public $notice;
	public $keyword;
	public $msgnotice;
	abstract function receive();
}
abstract class WeModuleSite extends WeBase {
	public $inMobile;
	public function __call($name='', $params='') {
		$isWeb = stripos($name, 'doWeb') === 0;
		$isMobile = stripos($name, 'doMobile') === 0;
		if($isWeb || $isMobile) {
			$dir = ROOT_D . '/addons/' . $this->modulename . '/inc/';
			if($isWeb) {
				$dir .= 'web/';
				$fun = strtolower(substr($name, 5));
			}
			if($isMobile) {
				$dir .= 'mobile/';
				$fun = strtolower(substr($name, 8));
			}
			$file = $dir . $fun . '.inc.php';
			if(file_exists($file)) {
				require $file;
				exit;
			} else {
				$dir = str_replace("addons", "api/open_jyapi/builtin", $dir);
				$file = $dir . $fun . '.inc.php';
				if(file_exists($file)) {
					require $file;
					exit;
				}
			}
		}
		trigger_error("方法 {$name} 不存在.", E_USER_WARNING);
		return null;
	}
	protected function pay($params = array(), $mine = array()) {
		global $_AR;
		if($_SESSION['this']!='custom') {
			exit('支付功能只能在手机上使用');
		}
		$parameter=array(
			'id'=>$params['tid'],
			'fee'=>$params['fee'],
			'plugin'=>$this->modulename,
		);
		cfc('core')->pay($parameter);
	}
	public function payResult($ret) {
		global $_AR;
		if($ret['from'] == 'return') {
			if ($ret['type'] == 'credit2') {
				message('已经成功支付', url('mobile/channel', array('name' => 'index', 'weid' => $_AR['weid'])));
			} else {
				message('已经成功支付', '../../' . url('mobile/channel', array('name' => 'index', 'weid' => $_AR['weid'])));
			}
		}
	}
	protected function payResultQuery($tid) {
		$params = array('module'=>$this->module['name'],'tid'=>$tid);
		$pay_log = pdo_get('core_pay_log', $params);
		$res = array();
		if(!empty($pay_log)) {
			$res['uniacid'] = $pay_log['uniacid'];
			$res['result'] = $pay_log['status'] == '1' ? 'success' : 'failed';
			$res['type'] = $pay_log['type'];
			$res['from'] = 'query';
			$res['tid'] = $pay_log['tid'];
			$res['user'] = $pay_log['openid'];
			$res['fee'] = $pay_log['fee'];
		}
		return $res;
	}
	protected function share($params = array()) {
		global $_AR;
		$access=array(
			'module' => $params['module'],
			'action' => $params['action'],
			'sign' => $params['sign'],
			'uid' => $params['uid']
		);
		$url = murl('utility/share', $access);
		echo <<<EOF
		<script>
			window.onshared = function(){
				var url = "{$url}";
				$.post(url);
			}
		</script>
EOF;
	}
	protected function click($params = array()) {
		global $_AR;
		$access=array(
		'module' => $params['module'],
		'action' => $params['action'],
		'sign' => $params['sign'],
		'tuid' => $params['tuid'],
		'fuid' => $params['fuid']
		);
		$url = murl('utility/click', $access);
		echo <<<EOF
		<script>
			var url = "{$url}";
			$.post(url);
		</script>
EOF;
	}
}
abstract class WeModuleCron extends WeBase {
	public function __call($name='', $params='') {
		if($this->modulename == 'task') {
			$dir = ROOT_D . '/api/open_jyapi/builtin/task/cron/';
		} else {
			$dir = ROOT_D . '/addons/' . $this->modulename . '/cron/';
		}
		$fun = strtolower(substr($name, 6));
		$file = $dir . $fun . '.inc.php';
		if(file_exists($file)) {
			require $file;
			exit;
		}
		trigger_error("方法 {$name} 不存在.", E_USER_WARNING);
		return error(-1009, "方法 {$name} 不存在.");
	}
		public function addCronLog($tid, $errno='', $note='', $tag = array()) {
		global $_AR;
		if(!$tid) {
			message(error(-1, 'tid参数错误'), '', 'ajax');
		}
		$data = array(
			'uniacid' => $_SESSION['uniacid'],
			'module' => $this->modulename,
			'type' => $_AR['cron']['filename'],
			'tid' => $tid,
			'note' => $note,
			'tag' => iserializer($tag),
			'createtime' => TIMESTAMP
		);
		pdo_insert('core_cron_record', $data);
		$exi=error($errno, $note);
		message($exi,'', 'ajax');
	}
}
function parse($msgnotice) {
		if (!empty($msgnotice)){
			$packet = iarray_change_key_case($msgnotice, CASE_LOWER);
			$packet['from'] = $msgnotice['FromUserName'];
			$packet['to'] = $msgnotice['ToUserName'];
			$packet['time'] = $msgnotice['CreateTime'];
			$packet['type'] = $msgnotice['MsgType'];
			$packet['event'] = $msgnotice['Event'];
			switch ($packet['type']) {
				case 'text':
					$packet['redirection'] = false;
					$packet['source'] = null;
					break;
				case 'image':
					$packet['url'] = $msgnotice['PicUrl'];
					break;
				case 'video':
				case 'shortvideo':
					$packet['thumb'] = $msgnotice['ThumbMediaId'];
					break;
			}
			switch ($packet['event']) {
				case 'subscribe':
					$packet['type'] = 'subscribe';
				case 'SCAN':
					if ($packet['event'] == 'SCAN') {
						$packet['type'] = 'qr';
					}
					if(!empty($packet['eventkey'])) {
						$packet['scene'] = str_replace('qrscene_', '', $packet['eventkey']);
						if(strexists($packet['scene'], 'u')) {
							$packet['scene'] = '"' . str_replace('\u', 'u', $packet['scene']) . '"';
							$packet['scene'] = json_decode($packet['scene']);
						}
					}
					break;
				case 'unsubscribe':
					$packet['type'] = 'unsubscribe';
					break;
				case 'LOCATION':
					$packet['type'] = 'trace';
					$packet['location_x'] = $msgnotice['Latitude'];
					$packet['location_y'] = $msgnotice['Longitude'];
					break;
				case 'pic_photo_or_album':
				case 'pic_weixin':
				case 'pic_sysphoto':
					$packet['sendpicsinfo']['piclist'] = array();
					$packet['sendpicsinfo']['count'] = $msgnotice['SendPicsInfo']['Count'];
					if (!empty($msgnotice['SendPicsInfo']['PicList'])) {
						foreach ($msgnotice['SendPicsInfo']['PicList']['item'] as $item) {
							if (empty($item)) {
								continue;
							}
							$packet['sendpicsinfo']['piclist'][] = is_array($item) ? $item['PicMd5Sum'] : $item;
						}
					}
					break;
				case 'card_pass_check':
				case 'card_not_pass_check':
				case 'user_get_card':
				case 'user_del_card':
				case 'user_consume_card':
				case 'poi_check_notify':
					$packet['type'] = 'coupon';
					break;
			}
		}
		return $packet;
}
function iarray_change_key_case($array, $case_lower = CASE_LOWER){
	$array=model('core/tools')->iarray_change_key_case($array, $case_lower);
	return $array;
}